package com.poker.service;

import com.poker.entity.Permission;
import com.poker.entity.Role;
import com.poker.repository.RoleRepository;
import com.poker.util.Misc;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class RoleService {
    @Resource
    private RoleRepository repository;

    public List<Role> findAll() {
        return repository.findAll();
    }

    public void save (Role sysRole) {
        repository.save(sysRole);
    }

    public Role getById(String id) {
        return repository.getOne(id);
    }

    public void deleteById(String id) {
        repository.deleteById(id);
    }
    
    /**
     * @param: [page, size];
     * @return: org.springframework.data.domain.Page<Role>;
     * @Description: 不带条件分页查询;
     */
    public Page<Role> findRoleNoCriteria(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "id");

        return getPermissionNames(repository.findAll(pageable));
    }

    /**
     * @param: [page, size, role];
     * @return: org.springframework.data.domain.Page<Role>;
     * @Description: 带条件分页查询;
     */
    public Page<Role> findRoleCriteria(Integer page, Integer size, Role role) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "id");

        return getPermissionNames(repository.findAll((Specification<Role>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            if (Misc.isNotEmpty(role.getRole()))
                list.add(criteriaBuilder.equal(root.get("role").as(String.class), role.getRole()));
            if (Misc.isNotEmpty(role.getRoleName()))
                list.add(criteriaBuilder.equal(root.get("roleName").as(String.class), role.getRoleName()));

            Predicate[] predicateArray = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(predicateArray));
        }, pageable));
    }

    private Page<Role> getPermissionNames(Page<Role> roles) {
        for (Role role: roles) {
            StringBuilder permissionNames = new StringBuilder();
            Set<Permission> permissions = role.getPermissions();

            int count = 0;
            int size = permissions.size();
            for (Permission permission: permissions) {
                count++;
                if (count == size) permissionNames.append(permission.getName());
                else permissionNames.append(permission.getName()).append(",");
            }

            role.setPermissionNames(permissionNames.toString());
        }

        return roles;
    }
}
